<template>
  <div class="cusTable" ref="cusTable">
    <!-- 搜索框 -->
    <div class="search_body" ref="search_body">
      <div class="search_form" v-if="showSearchFrom">
        <div class="form_item" v-for="(data, index) in searchFrom" :key="index">
          <div class="form_item_label"
            :style="{ width: data.width ? `${data.width}px` : '90px', flexBasis: data.width ? `${data.width}px` : '90px' }">
            {{ data.label }}
          </div>
          <div class="form_item_input">
            <el-input size="small" clearable v-model="formData[data.value]" :clearable="data.clearable" v-if="data.type === 'input'"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              :placeholder="data.placeholder"  oninput="value=value.replace(/ +/g, ''); " ></el-input>
            <el-date-picker
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              size="small"
              clearable
              :default-time="['00:00:00', '23:59:59']"
              v-model="formData[data.value]" v-if="data.type === 'datePickerDatetime'" type="daterange"
              range-separator="至" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" start-placeholder="开始日期"
              end-placeholder="结束日期">
            </el-date-picker>
            <el-date-picker
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              size="small"
              clearable
              v-model="formData[data.value]" v-if="data.type === 'datePicker'" type="daterange"
              range-separator="至" format="yyyy-MM-dd" value-format="yyyy-MM-dd" start-placeholder="开始日期"
              end-placeholder="结束日期">
            </el-date-picker>
            <el-date-picker size="small"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              v-model="formData[data.value]" clearable type="year" v-if="data.type === 'datePickeryear'"
              :placeholder="data.placeholder">
            </el-date-picker>
            <el-date-picker size="small" clearable v-model="formData[data.value]" v-if="data.type === 'monthrange'"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              type="monthrange" :unlink-panels="true" :clearable="data.clearable" format="yyyy-MM" value-format="yyyy-MM"
              range-separator="至" start-placeholder="开始月份" end-placeholder="结束月份">
            </el-date-picker>

            <el-date-picker clearable v-model="formData[data.value]" v-if="data.type === 'datetime'" size="small" type="datetime"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              :placeholder="data.placeholder" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss">
            </el-date-picker>

            <el-date-picker clearable size="small" v-model="formData[data.value]" v-if="data.type === 'date'" type="date"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              :placeholder="data.placeholder" format="yyyy-MM-dd" value-format="yyyy-MM-dd">
            </el-date-picker>

            <el-date-picker clearable size="small" v-model="formData[data.value]" v-if="data.type === 'month'" format="yyyy-MM"
              value-format="yyyy-MM"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              :placeholder="data.placeholder" type="month">
            </el-date-picker>

            <el-date-picker clearable size="small" v-model="formData[data.value]" v-if="data.type === 'year'" type="year"
              placeholder="选择年度" format="yyyy"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              value-format="yyyy">
            </el-date-picker>

            <el-select size="small" :disabled="data.disabled? data.disabled:false"  :filter-method="data.filterMethod ? data.filterMethod: ()=>{}"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              :clearable="data.clearable" filterable :multiple="data.multiple" v-if="data.type === 'select'"
              v-model="formData[data.value]" :placeholder="data.placeholder" @change="selecChange">
              <el-option v-for="item in data.options" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>

            <el-cascader size="small" clearable :props="data.options" v-if="data.type === 'cascader'" @change="cascaderChange"
              ref="myCascader"
              :style="{ width: data.editWidth ? `${data.editWidth}px` : `240px`, flexBasis: data.editWidth ? `${data.editWidth}px` : `240px` }"
              v-model="formData[data.value]" :placeholder="data.placeholder"></el-cascader>
          </div>
        </div>
        <slot name="searchSlot"></slot>
        <div class="form_item">
          <!--          <template v-if="searchFrom && searchFrom.length !== 0">-->
          <!--            <el-button v-show="!showSearchFrom" type="success" icon="el-icon-caret-bottom" plain size="small"-->
          <!--                       @click="showOrHideSearch">展开搜索条件</el-button>-->
          <!--            <el-button v-show="showSearchFrom" type="danger" icon="el-icon-caret-top" plain size="small"-->
          <!--                       @click="showOrHideSearch">关闭搜索条件</el-button>-->
          <!--          </template>-->
          <el-button type="primary" icon="el-icon-search" size="small" @click="onSubmit" v-if="hasSearch">查询
          </el-button>
          <el-button v-if="hasSearch" @click="resetForm('ruleForm')" size="small" icon="el-icon-refresh-right"
                     class="theme-color-0fb6da theme-color-0fb6da-border">重置
          </el-button>
          <slot name="btnSlot"></slot>
        </div>
      </div>
      <div class="search_btn">
      </div>
    </div>
    <!-- 表格 -->
    <div class="table_body">
      <el-table  ref="tableDataRef" class="el-table"
                size="small"
                v-if="tableHeight !== 0"
                :header-cell-class-name="cellClass"
                v-loading="loading"
                :cell-style="cellStyle"
                :cell-class-name="tableCellClassName"
                :row-class-name="tableRowClassName"
                default-expand-all
                :row-key="getRowKeys"
                :stripe="stripe" align="center"
                :header-cell-style="{
          background: '#EBEEF4',
          borderColor: '#DCDCDC',
          color: '#919293',
        }" :height="tableHeight" border :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" :indent="20"
        :data="tableData" @select="handleSelectionSingleChange" @selection-change="handleSelectionChange" @sort-change="tableSort"
        style="width: 100%">
        <el-table-column  :selectable="isRowSelectable"  v-if="hasTableSelect" type="selection" :width="hasTableSelectToMultiple ? 55 : singleSelectionWidth" >
        </el-table-column>
        <el-table-column v-for="(data, index) in tableClass" :key="data.index || index" :width="data.width" :sortable="data.sortable"
         :show-overflow-tooltip="data.noShowTooltip?false :true"
          :prop="data.prop" :label="data.label" :render-header="data.renderHeader">
          <template slot-scope="scope">
            <slot :name="data.prop" :data="scope.row" v-if="!data.supportHtml">
              <span>{{ scope.row[data.prop] }}</span>
            </slot>
            <slot :name="data.prop" :data="scope.row" v-if="data.supportHtml">
              <div v-html="scope.row[data.prop]"></div>
            </slot>
          </template>
        </el-table-column>
        <template v-if="operate">
          <template v-if="orOperateFixed">
            <el-table-column label="操作" fixed="right" :width="operateWidth">
              <template slot-scope="scope">
                <slot :data="scope.row"></slot>
              </template>
            </el-table-column>
          </template>
          <template v-else>
            <el-table-column label="操作" :width="operateWidth">
              <template slot-scope="scope">
                <slot :data="scope.row"></slot>
              </template>
            </el-table-column>
          </template>
        </template>
      </el-table>
    </div>
    <!-- 分页器 -->
    <div class="pagination_body" ref="pagination_body" v-if="hasPagination">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage"
        :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper"
        :total="total">
      </el-pagination>
    </div>
  </div>
</template>
<script>
import {
  getNowDay,
  getEndNowDay,
  getStartDayOfWeek,
  getEndDayOfWeek,
  getStartDayOfMonth,
  getEndDayOfMonth,
} from "@/plugins/pikerData";
export default {
  name: "cusTable",
  data() {
    return {
      currentPage: 1,
      pageSize: 10,
      tableHeight: 0,
      showSearchFrom: true,
      pickerOptions: {
        shortcuts: [
          {
            text: "当日",
            onClick(picker) {
              const end = getEndNowDay();
              const start = getNowDay();
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "本周",
            onClick(picker) {
              const end = getEndDayOfWeek();
              const start = getStartDayOfWeek();

              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "本月",
            onClick(picker) {
              const end = getEndDayOfMonth();
              const start = getStartDayOfMonth();
              picker.$emit("pick", [start, end]);
            },
          },
        ],
      },
    };
  },
  props: {
    loading: {
      type: Boolean,
      default: false,
    },
    orOperateFixed: {
      type: Boolean,
      default: false,
    },
    total: {
      type: Number,
      default: 1000,
    },
    searchFrom: {
      type: Array,
      defaults: () => {
        return [];
      },
    },
    formData: {
      type: Object,
      defaults: () => {
        return [];
      },
    },
    tableClass: {
      type: Array,
      defaults: () => {
        return [];
      },
    },
    tableData: {
      type: Array,
      defaults: () => {
        return [];
      },
    },
    hasPagination: {
      type: Boolean,
      default: true,
    },
    hasSearch: {
      type: Boolean,
      default: true,
    },
    operate: {
      type: Boolean,
      default: true,
    },
    hasTableSelect: {
      type: Boolean,
      default: false,
    },
    hasTableSelectToMultiple: {
      type: Boolean,
      default: true,
    },
    singleSelectionWidth: {
      type: [String, Number],
      default: "80",
    },
    operateWidth: {
      type: [String, Number],
      default: "100",
    },

    isRowSelectable: {
      type: Function,
      default: () => {
        return true;
      },
    },
    tableRowClassName: {
      type: Function,
      default: () => {
        return "nomal-row";
      },
    },
    cellStyle: {
      type: Function,
      default: () => {
        return { borderColor: '#ccc' };
      },
    },
    tableCellClassName: {
      type: Function,
      default: () => {
        return '';
      },
    },
    stripe: {
      type: Boolean,
      default: false,
    },
  },
  //监听tableData的变化
  watch: {
    // 解决element table的bug， el-table__body-wrapper自适应失败
    tableData: {
      handler(newVal, oldVal) {
        if(newVal){
          this.$nextTick(() => {
            this.$refs.tableDataRef?.doLayout();
            newVal.forEach((v, i) => {
                if (v.check) {
                  this.$refs.tableDataRef.toggleRowSelection(v, true);
                }});
          });
        }
      }
    },

  },
  methods: {

    getRowKeys(row) {
      if (row.id) {
        return row.id
      } else {
        return row.index
      }
    },
    showOrHideSearch() {
      this.showSearchFrom = !this.showSearchFrom
      this.tableHeight = 0
      this.$nextTick(() => {
        this.getTableHeight()
      })
    },
    // 设置表头的class
    cellClass(row) {
      if (!this.hasTableSelectToMultiple) {
        if (row.columnIndex === 0) {
          return 'disabledSelection';
        }
      }
    },
    load(tree, treeNode, resolve) {
      this.$emit("getAccompanyingInfoCardLoadData", tree, treeNode, resolve);
    },
    handleSelectionSingleChange(val, row) {
      if (this.hasTableSelectToMultiple) {
        if (row.check) {
            this.$refs.tableDataRef.toggleRowSelection(row, true);
          }
        this.$emit("multipleSelection", val);
      } else {
        this.$refs.tableDataRef.clearSelection()
        if (val.length === 0) {
          // 判断selection是否有值存在
          return
        }
        if (row) {
          let selectioned = row;
          this.$refs.tableDataRef?.toggleRowSelection(row, true);
          this.$emit("singleSelection", selectioned);

        }
      }
    },
    tableSort({ column, prop, order }) {
        this.$emit("tableSort", { column, prop, order });
      
    },
    handleSelectionChange(val, row) {
      if (this.hasTableSelectToMultiple) {
        this.$emit("multipleSelection", val);
      }
    },

    handleSizeChange(val) {
      this.pageSize = val;
      this.$emit("onSubmit", {
        size: this.pageSize,
        page: this.currentPage,
        formData: this.formData,
      });
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.$emit("onSubmit", {
        size: this.pageSize,
        page: this.currentPage,
        formData: this.formData,
      });
    },
    onSubmit() {
      this.currentPage = 1;
      this.$emit("onSubmit", {
        size: this.pageSize,
        page: this.currentPage,
        formData: this.formData,
      });
    },
    resetForm() {
      this.currentPage = 1;
      for (let i in this.formData) {
        this.formData[i] = "";
      }
      this.$emit("onSubmit", {
        size: this.pageSize,
        page: this.currentPage,
        formData: this.formData,
      });
    },
    getTableHeight() {
      if (this.hasPagination) {
        this.tableHeight = this.$refs.cusTable.clientHeight - 20 - this.$refs.search_body.clientHeight - this.$refs.pagination_body.clientHeight;
      } else {
        this.tableHeight = this.$refs.cusTable.clientHeight - 20 - this.$refs.search_body.clientHeight;
      }
    },
    //form表单select改变时触发
    selecChange(value) {
      this.$emit("selecChange", value);
    },
    //form表单cascaderChange改变时触发
    cascaderChange(value) {
      this.$emit("cascaderChange", value);
    },
    //check=true 默认选中
    defaultChecked() {
      var that = this;
      if(this.tableData){
        that.$nextTick(() => {
          setTimeout(() => {
            if( this.tableData && this.tableData?.length>0){
              this.tableData?.forEach((v, i) => {
                if (v.check) {
                  this.$refs.tableDataRef.toggleRowSelection(v, true);
                }});
            }
          },100);
        });
      }
    }
  },
  created(){
    // if(this.hasTableSelectToMultiple){
       setTimeout(() => {
        this.defaultChecked();
      }, 100);
    // }

  },
  mounted() {
    this.$nextTick(() => {
      this.getTableHeight();
      window.onresize = () => {
        if (this.$refs.cusTable && this.$refs.search_body) {
          this.getTableHeight();
        }
      };



    });


  },
};
</script>
<style scoped lang="scss">
.cusTable {
  display: flex;
  flex-direction: column;
  height: 100%;
  // background: #ffffff;
  box-sizing: border-box;

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }

  .clearfix:after {
    clear: both;
  }

  .icon-zhongzhi,
  .icon-sousuo {
    font-size: 18px;
    cursor: pointer;
    vertical-align: middle;
  }

  .table_body {
    width: 100%;
    box-sizing: border-box;
    .el-table{
      border: 1px solid #ccc;

    }
  }

  .pagination_body {
    width: 100%;
    height: auto;
    text-align: right;
    box-sizing: border-box;
    padding: 8px 0;
  }
}

.search_body{
  padding: 8px 8px 0px 8px;
  box-sizing: border-box;
  background: #ffffff;
  margin-bottom: 6px;
}
.search_form {
  width: 100%;
  height: auto;
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-wrap: wrap;
  overflow: hidden;

  .form_item {
    // width: 25%;
    // flex-basis: 25%;
    flex-shrink: 1;
    //float: left;
    width: max-content;
    height: auto;
    margin-bottom: 10px;
    display: flex;
    display: -webkit-flex;
    display: -moz-flex;
    align-items: center;
    margin-right: 10px;

    .form_item_label {
      width: 90px;
      flex-basis: 90px;
      flex-shrink: 0;
      height: auto;
      font-family: "Helvetica Neue", Helvetica, "PingFang SC",
        "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
      font-size: 14px;
      color: #333333;
    }

    .form_item_input {
      //width: calc(100% - 90px);
      //flex-basis: calc(100% - 90px);
      width: max-content;
      flex-shrink: 0;
      height: auto;
      box-sizing: border-box;
      padding-right: 20px;
    }
  }
}

.search_btn {
  width: 100%;
  height: auto;
  overflow: hidden;
  box-sizing: border-box;
  padding-bottom: 10px;
  text-align: center;
  position: relative;
}

.table_body,.pagination_body{
  padding: 8px 8px 0px 8px;
  background: #ffffff;
  box-sizing: border-box;

}
::v-deep .el-checkbox__inner {
  border: 1px solid #409EFF;
}


::v-deep thead .cell {
  width:100%;
  font-size: 14px;
  color: #333333;
  text-overflow: ellipsis;
  overflow: hidden;
  word-break: break-all;
  white-space: nowrap;
}
</style>
